home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvibook / libtex / tempfile.c < prev    next >
C/C++ Source or Header  |  1994-03-18  |  2KB  |  78 lines

  1. /*
  2.  * Copyright (c) 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/tempfile.c,v 3.1 89/08/22 21:45:20 chris Exp $";
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <sys/file.h>
  15.  
  16. char    *getenv();
  17.  
  18. /*
  19.  * Create an open but unlinked (i.e., remove-on-exit-or-file-close)
  20.  * file.  Return the file descriptor, or -1 if unable to create such
  21.  * a file.  The buffer `name' is used to hold the file name (so that
  22.  * if this returns -1, it is useful for error messages).
  23.  *
  24.  * We use the despicable trick of unlinking an open temporary file.
  25.  * The alternatives are too painful.  If it becomes necessary to
  26.  * do this another way, however, here is a method suggested by Fred
  27.  * Blonder: fork, and have the parent wait for the child to exit.
  28.  * (The parent must avoid being killed during this phase.)  When
  29.  * the child exits, the parent should then remove the temporary file,
  30.  * then exit with the same status, or send itself the same signal.
  31.  */
  32. int
  33. MakeRWTempFile(name)
  34.     register char *name;
  35. {
  36.     register int tf, n;
  37.     int mypid, tries;
  38.     char *tmpdir;
  39.  
  40.     if ((tmpdir = getenv("TMPDIR")) == NULL)
  41.         tmpdir = "/tmp";
  42.  
  43.     /* compose a suitable temporary file name, and get an r/w descriptor */
  44.     mypid = getpid();
  45.     n = 0;
  46.     tries = 0;
  47.     do {
  48.         (void) sprintf(name, "%s/#%d.%d", tmpdir, mypid, n++);
  49.         (void) unlink(name);
  50. #ifdef O_CREAT            /* have three-argument open syscall */
  51.         tries++;
  52.         tf = open(name, O_RDWR | O_CREAT | O_EXCL, 0666);
  53. #else
  54.         if (access(name, 0) == 0) {
  55.             /*
  56.              * Skip existing files.  Note that tf might
  57.              * not be set yet.
  58.              */
  59.             tf = -1;
  60.             continue;
  61.         }
  62.         tries++;
  63.         tf = creat(name, 0666);
  64.         if (tf >= 0) {
  65.             (void) close(tf);
  66.             tf = open(name, 2);
  67.             if (tf < 0)
  68.                 (void) unlink(name);
  69.         }
  70. #endif
  71.     } while (tf < 0 && tries < 20);
  72.     if (tf < 0)        /* probably unrecoverable user error */
  73.         return (-1);
  74.  
  75.     (void) unlink(name);
  76.     return (tf);
  77. }
  78.